package com.JavaNet.chapter7_urlConnection;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

/**
 * @author : wushikai
 * <p>
 * date : 2021-04-19
 */
public class HttpUrlConnectionDemo {


    protected static class User implements Serializable {

        String username;

        String password;

        String token ;

        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }

        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }


    private static final String SIMPLE_URL = "http://localhost:8888/api/login";
    private static final String TEST_URL = "http://localhost:8888/api/test";
    private static final String PARAM_URL = "http://localhost:6690/login?username=admin&password=123456";
    String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxIn0.qfd0G-elhE1aGr15LrnYlIZ_3UToaOM5HeMcXrmDGBM";



    /**
     * 登陆到自创的 web 服务, 想要演示这个方法 , 请搭一个自己的服务
     */
    private static void login2Agent() throws Exception {

        //2.发起一个请求
        URL url = new URL(TEST_URL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        //2.1 添加请求方式
        connection.setRequestMethod("POST");
        //2.2 添加请求头------如果编写爬虫，真实浏览器发送的header都拷贝
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestProperty("Connection","keep-alive");
        connection.setUseCaches(false);
        connection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36");
        connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

        //2.3 发送一些数据
        connection.setDoOutput(true);
        connection.setDoInput(true);
        OutputStream outputStream = connection.getOutputStream();
        // 编写什么样格式的数据？  username=zhangsan&passwd=123
        connection.connect();

        outputStream.write(("username=admin&password=123456").getBytes());
        outputStream.flush();
        outputStream.close();

        //3.获取返回值
        String responseMessage = connection.getResponseMessage();
        System.out.println(responseMessage);
        InputStream inputStream = connection.getInputStream();
        //3.1 将输入流转换字符串
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        //3.2 一次读取bufferReader的数据
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
        //4.关闭流
        inputStream.close();


    }


    /**
     *
     * 使用 HttpURLConnection 对象 , 来获取从服务端传来的消息 ;
     *
     * */
    private static void testHttpURLConnection() {
        try {
            URL url = new URL(SIMPLE_URL);

            URLConnection rulConnection = url.openConnection();

            // 此处的urlConnection对象实际上是根据URL的
            // 请求协议(此处是http)生成的URLConnection类 的子类HttpURLConnection,故此处最好将其转化
            // 为HttpURLConnection类型的对象,以便用到 HttpURLConnection更多的API.如下:
            HttpURLConnection httpUrlConnection = (HttpURLConnection) rulConnection;

            // 设置是否向httpUrlConnection输出，因为这个是post请求，参数要放在
            // http正文内，因此需要设为true, 默认情况下是false;
            httpUrlConnection.setDoOutput(true);

            // 设置是否从httpUrlConnection读入，默认情况下是true;
            httpUrlConnection.setDoInput(true);

            // Post 请求不能使用缓存
            httpUrlConnection.setUseCaches(false);

            // 设定传送的内容类型是可序列化的java对象
            // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
            //httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");

            //使用传统的 URL 表单 请求格式
            httpUrlConnection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            // 设定请求返回的格式是json
            httpUrlConnection.setRequestProperty("Accept", "application/json");

            // 设定请求的方法为"POST"，默认是GET
            httpUrlConnection.setRequestMethod("POST");

            // 连接，从上述第2条中url.openConnection()至此的配置必须要在connect之前完成，
            httpUrlConnection.connect();

            // 此处getOutputStream会隐含的进行connect(即：如同调用上面的connect()方法，
            // 所以在开发中不调用上述的connect()也可以)。
            OutputStream outputStream = httpUrlConnection.getOutputStream();


            // 现在通过输出流对象构建对象输出流对象，以实现输出可序列化的对象。
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);

            // 向对象输出流写出数据，这些数据将存到内存缓冲区中
            objectOutputStream.writeObject( "username=admin&password=123456" );

            // 刷新对象输出流，将任何字节都写入潜在的流中（些处为ObjectOutputStream）
            objectOutputStream.flush();

            // 关闭流对象。此时，不能再向对象输出流写入任何数据，先前写入的数据存在于内存缓冲区中,
            // 在调用下边的getInputStream()函数时才把准备好的http请求正式发送到服务器
            objectOutputStream.close();

            // 调用HttpURLConnection连接对象的getInputStream()函数,
            // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。
            InputStream inputStream = httpUrlConnection.getInputStream(); // <===注意，实际发送请求的代码段就在这里

            // 上边的httpConn.getInputStream()方法已调用,本次HTTP请求已结束,下边向对象输出流的输出已无意义，
            // 既使对象输出流没有调用close()方法，下边的操作也不会向对象输出流写入任何数据.
            // 因此，要重新发送数据时需要重新创建连接、重新设参数、重新创建流对象、重新写数据、
            // 重新发送数据(至于是否不用重新这些操作需要再研究)

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            //3.2 一次读取bufferReader的数据
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }




    public static void main(String[] args) throws Exception {
       // login2Agent();
        testHttpURLConnection();

    }

}
